package fr.emse.tatiana.replayable.tabulardisplay;



import java.util.List;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;


import fr.emse.tatiana.replayable.CreatedReplayableInput;
import fr.emse.tatiana.replayable.IReplayableSaver;
import fr.emse.tatiana.replayable.ReplayableEvent;
import fr.emse.tatiana.replayable.ReplayableModel;
import fr.emse.tatiana.replayable.SynchronisationEvent;

public class ReplayableTabularEditor extends
		ReplayableTabularViewer {
	
	public static final String ID = "fr.emse.tatiana.ReplayableTabularEditor";

	private CreatedReplayableInput input;
	private Button create;
	private Label anchor;

	/* (non-Javadoc)
	 * @see fr.emse.tatiana.replayable.tabulardisplay.TabularDisplayEditor#createPages()
	 */
	@Override
	protected void createPages() {
		createTablePage();
	}

	private Composite c;

	private Button delete;

	private Button moveup;

	private Button movedown;
	
	private Button split;
	
	private void createTablePage() {
		c = new Composite(getContainer(),SWT.NONE);

		
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns=6; // match number of buttons
		gridLayout.verticalSpacing=10;
		gridLayout.marginHeight=0;
		gridLayout.marginWidth=0;
		c.setLayout(gridLayout);
	
		createTable(c);
		GridData griddata = new GridData(GridData.FILL,GridData.FILL,true,true);
		griddata.horizontalSpan = gridLayout.numColumns; // span all columns
		table.setLayoutData(griddata);
		
		
		tableviewer.addSelectionChangedListener(new ISelectionChangedListener() {

			public void selectionChanged(SelectionChangedEvent event) {
				StructuredSelection sel = (StructuredSelection)tableviewer.getSelection();
				currentselection = sel.toList();
				delete.setEnabled(currentselection.size()>0);
				moveup.setEnabled(currentselection.size()>0);
				movedown.setEnabled(currentselection.size()>0);
				split.setEnabled(currentselection.size()==1);
			}
			
		});
				
		setShower(input.getDisplayModel(analyses));
		
		
		
		GridData anchorgriddata = new GridData();
		anchorgriddata.horizontalSpan = gridLayout.numColumns; // span all columns
		
		anchor = new Label(c,SWT.NONE);
		anchor.setLayoutData(anchorgriddata);
		anchor.setText("                                     ");

		

		GridData creategriddata = new GridData();
		
		create = new Button(c, SWT.PUSH);
		create.setLayoutData(creategriddata);
		create.setText("Create Event From Selection");
		create.addSelectionListener(new SelectionListener(){
		
			public void widgetDefaultSelected(SelectionEvent e) {
				// doesn't happen	
			}

			public void widgetSelected(SelectionEvent e) {
				createLine();
			}
		});
		create.setEnabled(false);

		creategriddata = new GridData();
		delete = new Button(c, SWT.PUSH);
		delete.setLayoutData(creategriddata);
		delete.setText("Delete Selected Events");
		delete.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {
				// doesn't happen	
			}

			public void widgetSelected(SelectionEvent e) {
				deleteLines();
			}
		});
		delete.setEnabled(false);
		
		creategriddata = new GridData();
		moveup = new Button(c, SWT.PUSH);
		moveup.setLayoutData(creategriddata);
		moveup.setText("Move Selection Up");
		moveup.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {
				// doesn't happen	
			}

			public void widgetSelected(SelectionEvent e) {
				move(false);
			}
		});
		moveup.setEnabled(false);
		
		creategriddata = new GridData();
		movedown = new Button(c, SWT.PUSH);
		movedown.setLayoutData(creategriddata);
		movedown.setText("Move Selection Down");
		movedown.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {
				// doesn't happen	
			}

			public void widgetSelected(SelectionEvent e) {
				move(true);
			}
		});
		movedown.setEnabled(false);
		
		creategriddata = new GridData();
		split = new Button(c, SWT.PUSH);
		split.setLayoutData(creategriddata);
		split.setText("Split selected line");
		split.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {
				// doesn't happen	
			}

			public void widgetSelected(SelectionEvent e) {
				split();
			}
		});
		split.setEnabled(false);
		
		tablepageindex = addPage(c);
		setPageText(tablepageindex, "Replayable");
	}
	
	

	protected void move(boolean down) {
		if (down) {
			for (int i = currentselection.size()-1;i>=0;i--) {
				((ReplayableModel) shower).shiftEventDown((ReplayableEvent) currentselection.get(i));
			}
		} else {
			for (Object e: currentselection) {
				((ReplayableModel) shower).shiftEventUp((ReplayableEvent) e);
			}
		}
		
		//tableviewer.setInput(shower);
		tableviewer.refresh();
		firePropertyChange(PROP_DIRTY);
	}



	protected void deleteLines() {
		if (!MessageDialog.openConfirm(getSite().getShell(), "DeleteLine", "Are you sure you want to delete these lines")) {
			return;
		}
		for (Object e: currentselection) {
			((ReplayableModel) shower).removeEvent(e);
		}
//		tableviewer.setInput(shower);
		tableviewer.refresh();
		firePropertyChange(PROP_DIRTY);
	}



	protected void createLine() {
		Object o = ((ReplayableModel) shower).addEvent(currentevent);
		getRemote().addEvent(this, currentevent.getNow());
		//tableviewer.setInput(shower);
		tableviewer.refresh();
		tableviewer.setSelection(new StructuredSelection(o), true);
		firePropertyChange(PROP_DIRTY);
	}

	protected void split() {
		Object old = currentselection.get(0);
		Object neu = ((ReplayableModel) shower).duplicateEvent(old);
		if (activeCellEditor instanceof TextCellEditor && activeCellEditor.isActivated()) {
				TextCellEditor editor = (TextCellEditor) activeCellEditor;
				Text text = (Text) editor.getControl();
				String left = text.getText(0, text.getCaretPosition()-1);
				String right = text.getText(text.getCaretPosition(), text.getText().length());
				text.setText(left); // editor will set the facet value
				editor.deactivate(); // this doesn't seem to cancel editing
				shower.setFacetValue(old, activeColumn, left); // gets overridden by closing editor but left for elegance
				shower.setFacetValue(neu, activeColumn, right);
		}
		//tableviewer.setInput(shower);
		tableviewer.refresh();
		tableviewer.setSelection(new StructuredSelection(neu), true);
		firePropertyChange(PROP_DIRTY);
	}

	/* (non-Javadoc)
	 * @see fr.emse.tatiana.replayable.tabulardisplay.TabularDisplayEditor#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
	 */
	@Override
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		try {
			super.init(site, input);
		} catch (PartInitException pie) {
			// do nothing
		}
		
		if (input instanceof CreatedReplayableInput) {
			this.input = (CreatedReplayableInput) input;
		} else {
			throw new PartInitException("Bad input for Display");
		}
	}


	/* (non-Javadoc)
	 * @see fr.emse.tatiana.replayable.tabulardisplay.ReplayableTabularDisplayEditor#endSynchronisation()
	 */
	@Override
	protected void endSynchronisation() {
		try {
			anchor.setText("");
			create.setEnabled(false);
		} catch (Exception e) {
			System.out.println("OK, label already disposed");
		}
		super.endSynchronisation();
	}




	/* (non-Javadoc)
	 * @see fr.emse.tatiana.replayable.tabulardisplay.ReplayableTabularDisplayEditor#getReplayableSaver()
	 */
	@Override
	public IReplayableSaver getReplayableSaver() {
		return (ReplayableModel) shower;
	}


	/* (non-Javadoc)
	 * @see fr.emse.tatiana.replayable.tabulardisplay.ReplayableTabularDisplayEditor#goTo(fr.emse.tatiana.replayable.SynchronisationEvent)
	 */
	@Override
	public void goTo(SynchronisationEvent event) {
		super.goTo(event);
		currentevent=event;
		final String text = event.toString();
		PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
			public void run() {
				create.setEnabled(true);
				anchor.setText(text);
				anchor.pack(true);
			}
		});
		
	}
	
	protected SynchronisationEvent currentevent;
	protected List<Object> currentselection;

}
